<template>
  <div class="app-container">
    <div class="cylinder-2">
      <div class="cylinder">
        <div v-loading="!isOption1OK" class="chart" style="margin: 20px 10px 0 10px;">
          <Column v-if="isOption1OK" :option="option1" />
        </div>
      </div>
      <div class="cylinder">
        <div v-loading="!isOption1OK" class="chart" style="margin: 10px 10px 20px 10px;">
          <Column v-if="isOption1OK" :option="option2" />
        </div>
      </div>
    </div>

    <div class="cylinder-3">
      <div class="cylinder">
        <div class="selectDateClass">
          <span style="font-size: 18px; font-weight: bold">选择展示日期：</span>
          <el-date-picker
            v-model="selectDate"
            size="small"
            :clearable="false"
            type="date"
            style="width: 140px"
            value-format="yyyy-MM-dd"
            placeholder="选择日期"
            @change="changeDate"
          />

        </div>
      </div>

      <div class="cylinder">
        <div v-loading="!isOption3OK" class="chart" style="margin: 10px 10px 0 10px;">
          <Column v-if="isOption3OK" :option="option4" />
        </div>
      </div>
      <div class="cylinder">
        <div v-loading="!isOption3OK" class="chart" style="margin: 10px 10px 20px 10px;">
          <Column v-if="isOption3OK" :option="option5" />
        </div>
        <div v-loading="!isOption7OK" class="chart" style="margin: 10px 10px 20px 0;">
          <Column v-if="isOption7OK" :option="option7" />
        </div>
      </div>
    </div>

    <div class="tableClass">
      <!--查询表单-->
      <el-form :inline="true" class="demo-form-inline" size="small">
        <el-form-item label="爬虫名称">
          <el-autocomplete
            v-model="searchObj.codeName"
            :fetch-suggestions="querySearchAsync"
            :trigger-on-focus="false"
            placeholder="请输入爬虫名称"
            clearable
            @select="fetchData()"
            @keyup.enter="fetchData()"
          />
        </el-form-item>

        <el-form-item label="项目名称" label-width="80px">
          <el-select v-model="searchObj.projectName" clearable placeholder="请选择项目" @change="fetchData">
            <el-option
              v-for="item in projectNameList"
              :key="item.projectName"
              :label="item.projectName"
              :value="item.projectName"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="服务器" label-width="80px">
          <el-select v-model="searchObj.machine" clearable placeholder="请选择服务器" @change="fetchData">
            <el-option
              v-for="item in machineList"
              :key="item.machine"
              :label="item.machine"
              :value="item.machine"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="负责人" label-width="80px">
          <el-select v-model="searchObj.person" clearable placeholder="请选择负责人" @change="changePerson">
            <el-option
              v-for="item in personList"
              :key="item.person"
              :label="item.person"
              :value="item.person"
            />
          </el-select>
        </el-form-item>
      </el-form>

      <el-row :gutter="10" class="search-button">
        <el-col :span="1.5">
          <el-button
            ref="fetchData"
            type="primary"
            icon="el-icon-search"
            size="mini"
            @click="fetchData"
          >
            查询数据
          </el-button>
        </el-col>
        <el-col :span="1.5">
          <el-button
            ref="resetData"
            type="warning"
            icon="el-icon-refresh"
            size="mini"
            @click="resetData"
          >
            重置数据
          </el-button>
        </el-col>
      </el-row>

      <!--表格list-->
      <el-table
        ref="tableList"
        v-loading="loading"
        :data="list"
        :header-cell-style="headStyle"
        :cell-style="cellStyle"
      >
        <el-table-column prop="codeName" align="center" label="爬虫名称" />
        <el-table-column prop="projectName" align="center" label="项目名称" width="150" />
        <el-table-column prop="areaId" align="center" label="省份" width="120">
          <template slot-scope="scope">
            {{ getLabel(scope.row.areaId) }}
          </template>
        </el-table-column>
        <el-table-column prop="isJava" align="center" label="语言" width="120">
          <template slot-scope="scope">
            <el-tag v-if="scope.row.isJava === 0" type="success">
              python
            </el-tag>
            <el-tag v-else type="success">
              java
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="machine" align="center" label="所属服务器" width="150" />
        <el-table-column prop="tableName" align="center" label="数据表" width="120" />
        <el-table-column prop="person" align="center" label="负责人" width="120" />
        <el-table-column prop="lastTime" align="center" label="最近运行时间" width="120" />
        <el-table-column prop="remarks" align="center" label="备注" width="200">
          <template slot-scope="scope">
            <el-input v-model="scope.row.remarks" type="textarea" autosize size="small" name="title" @change="updateRemarks(scope.row)" />
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="150" class-name="small-padding fixed-width">
          <template slot-scope="scope">
            <router-link :to="'/analysis/detail/' + scope.row.id">
              <el-button icon size="mini" type="primary">
                <!--              <svg-icon icon-class="info" style="margin-right: 1px; width: 15px; height: 15px; padding-top: 2px" />-->
                爬虫分析
              </el-button>
            </router-link>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页组件 -->
      <el-pagination
        background
        :current-page="page"
        :total="total"
        :page-size="limit"
        :page-sizes="[10, 20, 50, 100]"
        prev-text="上一页"
        next-text="下一页"
        style="padding: 30px 0; text-align: center"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="changePageSize"
        @current-change="changeCurrentPage"
      />
    </div>
  </div>
</template>

<script>
import Column from '@/views/analysis/components/Column'
import analysisApi from '@/api/analysis/analysis'
import moment from 'moment'
import variables from '@/styles/variables.scss'
import crawlerApi from '@/api/crawler/crawler'
import { mapGetters } from 'vuex'

export default {
  name: 'Index',
  components: {
    Column
  },
  data() {
    // 计算七日
    const now = new Date()
    const sevenDays = []
    for (let i = 0; i < 7; i++) {
      const d = new Date(now - i * 24 * 3600 * 1000)
      const month = (d.getMonth() + 1).toString().padStart(2, '0')
      const date = d.getDate().toString().padStart(2, '0')
      sevenDays.unshift(`${month}-${date}`) // 将日期拼成字符串添加到数组尾部
    }
    const nowDay = moment().format('YYYY-MM-DD')
    return {
      selectDate: nowDay,
      isOption1OK: false,
      isOption3OK: false,
      isOption7OK: false,
      option1: {
        title: {
          text: '七日内入库数量分布图' // 图表名称
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow',
            label: {
              backgroundColor: '#6a7985'
            }
          }
        },
        legend: {
        },
        toolbox: {
          feature: {
            magicType: {
              show: true,
              type: ['line'],
              option: {
                line: {
                  smooth: false
                }
              }
            },
            restore: { show: true },
            saveAsImage: { show: true }
          }
        },
        grid: {
          left: '2%',
          right: '2%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: [
          {
            type: 'category',
            data: sevenDays
          }
        ],
        yAxis: [
          {
            type: 'value',
            name: 'success',
            position: 'left',
            alignTicks: true,
            axisLine: {
              show: true,
              lineStyle: {
              }
            },
            axisLabel: {
              formatter: '{value}'
            }
          },
          {
            type: 'value',
            name: 'warning',
            position: 'right',
            alignTicks: true,
            // offset: 75,
            axisLine: {
              show: true,
              lineStyle: {
                // color: '#d76464'
              }
            },
            axisLabel: {
              formatter: '{value}'
            }
          }
        ],
        series: [
          {
            name: 'success',
            type: 'bar',
            label: {
              show: true,
              position: 'top'
            },
            data: []
          },
          {
            name: 'warning',
            type: 'bar',
            label: {
              show: true,
              position: 'top'
            },
            yAxisIndex: 1,
            itemStyle: {
              // color: '#d76464'
            },
            // animationDelay: function(idx) {
            //   return idx * 10 + 1000
            // },
            data: []
          }
        ]
      },
      option2: {
        title: {
          text: '七日内警告数量分布图' // 图表名称
        },
        tooltip: {
          trigger: 'axis',
          z: 9999,
          axisPointer: {
            type: 'shadow',
            label: {
              backgroundColor: '#6a7985'
            }
          }
        },
        legend: {
        },
        toolbox: {
          feature: {
            magicType: {
              show: true,
              type: ['line'],
              option: {
                line: {
                  smooth: false
                }
              }
            },
            restore: { show: true },
            saveAsImage: { show: true }
          }
        },
        grid: {
          left: '2%',
          right: '2%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: [
          {
            type: 'category',
            data: sevenDays
          }
        ],
        yAxis: [
          {
            type: 'value',
            name: '',
            position: 'left',
            alignTicks: true,
            axisLine: {
              show: true,
              lineStyle: {
              }
            },
            axisLabel: {
              formatter: '{value}'
            }
          },
          {
            type: 'value',
            name: 'words',
            position: 'right',
            alignTicks: true,
            axisLine: {
              show: true,
              lineStyle: {
                color: '#727272'
              }
            },
            axisLabel: {
              formatter: '{value}'
            }
          }
        ],
        series: [
          {
            name: 'words',
            type: 'bar',
            label: {
              show: true,
              position: 'top'
            },
            yAxisIndex: 1,
            emphasis: {
              focus: 'series'
            },
            markLine: {
              symbol: 'none', // 不显示标记的图标
              label: {
                formatter: '{b}:{c}' // 标签显示刻度值
              },
              lineStyle: {
                type: 'dashed' // 横线样式，虚线
              },
              data: [
                { type: 'average', name: '平均值' }
              ]
            },
            itemStyle: {
              color: '#727272'
            },
            data: []
          }
        ]
      },
      option3: {
        title: {
          text: '24小时内入库数量分布图' // 图表名称
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'line',
            label: {
              backgroundColor: '#6a7985'
            }
          },
          formatter: function(params) {
            let category = params[0].name // {b} 对应的值
            const value = params[0].value // {c} 对应的值

            // 自定义处理逻辑
            category = category.replace(/(\d+)时/g, function(match, p1) {
              const num = parseInt(p1) // 将捕获到的数字字符串转换为整数
              return num + '时-' + (num + 1) + '时'
            })
            // 返回自定义格式化后的内容
            return category + '<br>' + '\u25CF ' + value
          }
        },
        legend: {
        },
        toolbox: {
          feature: {
            magicType: {
              show: true,
              type: ['bar']
              // option: {
              //   line: {
              //     smooth: false
              //   }
              // }
            },
            restore: { show: true },
            saveAsImage: { show: true }
          }
        },
        grid: {
          left: '2%',
          right: '2%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: [
          {
            type: 'category',
            boundaryGap: false,
            data: ['0时', '1时', '2时', '3时', '4时', '5时', '6时', '7时', '8时', '9时', '10时', '11时', '12时', '13时', '14时', '15时', '16时', '17时', '18时', '19时', '20时', '21时', '22时', '23时']
          }
        ],
        yAxis: [
          {
            type: 'value',
            name: 'success',
            position: 'left',
            alignTicks: true,
            axisLine: {
              show: true,
              lineStyle: {
              }
            },
            axisLabel: {
              formatter: '{value}'
            }
          },
          {
            type: 'value',
            name: '',
            position: 'right',
            alignTicks: true,
            // offset: 75,
            axisLine: {
              show: true
            },
            axisLabel: {
              formatter: '{value}'
            }
          }
        ],
        series: [
          {
            name: 'success',
            type: 'line',
            label: {
              show: true,
              position: 'top'
            },
            data: []
          }
        ]
      },
      option4: {
        title: {
          text: '24小时内警告数量分布图' // 图表名称
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'line',
            label: {
              backgroundColor: '#6a7985'
            }
          },
          formatter: function(params) {
            let category = params[0].name // {b} 对应的值
            const value = params[0].value // {c} 对应的值

            // 自定义处理逻辑
            category = category.replace(/(\d+)时/g, function(match, p1) {
              const num = parseInt(p1) // 将捕获到的数字字符串转换为整数
              return num + '时-' + (num + 1) + '时'
            })
            // 返回自定义格式化后的内容
            return category + '<br>' + '\u25CF ' + value
          }
        },
        legend: {
        },
        toolbox: {
          feature: {
            magicType: {
              show: true,
              type: ['bar'],
              option: {
                bar: {
                  itemStyle: {
                    color: '#d76464'
                  }
                }
              }
            },
            restore: { show: true },
            saveAsImage: { show: true }
          }
        },
        grid: {
          left: '2%',
          right: '2%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: [
          {
            type: 'category',
            boundaryGap: false,
            data: ['0时', '1时', '2时', '3时', '4时', '5时', '6时', '7时', '8时', '9时', '10时', '11时', '12时', '13时', '14时', '15时', '16时', '17时', '18时', '19时', '20时', '21时', '22时', '23时']
          }
        ],
        yAxis: [
          {
            type: 'value',
            name: 'warning',
            position: 'left',
            alignTicks: true,
            // offset: 75,
            axisLine: {
              show: true,
              lineStyle: {
                color: '#d76464'
              }
            },
            axisLabel: {
              formatter: '{value}'
            }
          },
          {
            type: 'value',
            name: '',
            position: 'right',
            alignTicks: true,
            // offset: 75,
            axisLine: {
              show: true
            },
            axisLabel: {
              formatter: '{value}'
            }
          }
        ],
        series: [
          {
            name: 'warning',
            type: 'line',
            label: {
              show: true,
              position: 'top'
            },
            lineStyle: {
              color: '#d76464'
            },
            itemStyle: {
              color: '#d76464'
            },
            // animationDelay: function(idx) {
            //   return idx * 10 + 1000
            // },
            data: []
          }
        ]
      },
      option5: {
        title: {
          text: '警告类型分布图' // 饼图
        },
        tooltip: {
          trigger: 'item'
        },
        legend: {
          top: '10%',
          left: 'center'
        },
        toolbox: {
          feature: {
            restore: { show: true },
            saveAsImage: { show: true }
          }
        },
        series: [
          {
            name: '',
            type: 'pie',
            radius: '50%',
            selectedMode: 'single',
            startAngle: 250,
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            },
            label: {
              position: 'outer',
              alignTo: 'edge',
              margin: 40,
              formatter: '{b}: {c} ({d}%)' // 显示名称、数量和百分比
            },
            data: []
          }
        ]
      },
      option7: {
        title: {
          text: '警告处理状态分布图' // 图表名称
        },
        tooltip: {
          trigger: 'item'
        },
        legend: {
          top: '10%',
          left: 'center'
        },
        toolbox: {
          feature: {
            restore: { show: true },
            saveAsImage: { show: true }
          }
        },
        series: [
          {
            name: '',
            type: 'pie',
            radius: '50%',
            selectedMode: 'single',
            startAngle: 250,
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            },
            label: {
              position: 'outer',
              alignTo: 'edge',
              margin: 40,
              formatter: '{b}: {c} ({d}%)' // 显示名称、数量和百分比
            },
            data: []
          }
        ]
      },
      list: [],
      loading: true,
      total: 0, // 数据库总记录数
      page: 1, // 默认页码
      limit: 10, // 每页记录数

      // 人员列表
      personList: [],

      // 服务器列表
      machineList: [],

      // 项目名称列表
      projectNameList: [],

      // 查询条件
      searchObj: {
        codeName: '',
        projectName: '',
        machine: '',
        person: '',
        spiderType: 0, // 爬虫类型
        userId: 0 // 数据置顶用的当前登录的用户的id
      },
      areaLabel: '',
      cityLabel: '',
      cities: [
        {
          value: 1,
          label: '中国'
        }, {
          value: 2,
          label: '北京'
        }, {
          value: 3,
          label: '安徽'
        }, {
          value: 4,
          label: '福建'
        }, {
          value: 5,
          label: '甘肃'
        }, {
          value: 6,
          label: '广东'
        }, {
          value: 7,
          label: '广西'
        }, {
          value: 8,
          label: '贵州'
        }, {
          value: 9,
          label: '海南'
        }, {
          value: 10,
          label: '河北'
        }, {
          value: 11,
          label: '河南'
        }, {
          value: 12,
          label: '黑龙江'
        }, {
          value: 13,
          label: '湖北'
        }, {
          value: 14,
          label: '湖南'
        }, {
          value: 15,
          label: '吉林'
        }, {
          value: 16,
          label: '江苏'
        }, {
          value: 17,
          label: '江西'
        }, {
          value: 18,
          label: '辽宁'
        }, {
          value: 19,
          label: '内蒙古'
        }, {
          value: 20,
          label: '宁夏'
        }, {
          value: 21,
          label: '青海'
        }, {
          value: 22,
          label: '山东'
        }, {
          value: 23,
          label: '山西'
        }, {
          value: 24,
          label: '陕西'
        }, {
          value: 25,
          label: '上海'
        }, {
          value: 26,
          label: '四川'
        }, {
          value: 27,
          label: '天津'
        }, {
          value: 28,
          label: '西藏'
        }, {
          value: 29,
          label: '新疆'
        }, {
          value: 30,
          label: '云南'
        }, {
          value: 31,
          label: '浙江'
        }, {
          value: 32,
          label: '重庆'
        }, {
          value: 33,
          label: '香港'
        }, {
          value: 34,
          label: '台湾'
        }, {
          value: 35,
          label: '澳门'
        }
      ]
    }
  },

  computed: {
    ...mapGetters([
      'id',
      'name',
      'roles',
      'person'
    ]),
    codeNameChange() {
      return this.searchObj.codeName
    }
  },
  created() {
    this.searchObj.userId = this.id
    this.searchObj.person = this.person
    this.initData()
  },
  methods: {
    // 初始化数据
    initData() {
      this.getOption1()
      this.getOption3()
      this.getOption7()
      this.fetchList()
      this.fetchData()
    },

    // 获取七日内数据
    getOption1() {
      const sevenDaysAgo = moment().subtract(7, 'days').format('YYYY-MM-DD')
      analysisApi.getOption1(null, sevenDaysAgo).then((response) => {
        // 七日内入库数量赋值
        this.option1.series[0].data = response.data.result.success
        this.option1.series[1].data = response.data.result.errors

        // 七日内警告数量赋值
        this.option2.series[0].data = response.data.result.words
        for (const [key, value] of Object.entries(response.data.result)) {
          if (key !== 'success' && key !== 'errors' && key !== 'words') {
            const obj = {
              name: key,
              type: 'bar',
              stack: '',
              label: {
                show: true,
                position: 'top'
              },
              emphasis: {
                focus: 'series'
              },
              data: value
            }
            this.option2.series.push(obj)
          }
        }
        this.isOption1OK = true
      })
    },

    // 获取24小时内数据
    getOption3() {
      this.isOption3OK = false
      analysisApi.getOption3(null, this.selectDate).then((response) => {
        // 24小时内入库数量赋值
        this.option3.series[0].data = response.data.result.success
        this.option4.series[0].data = response.data.result.errors

        // 24小时内警告错误类型数量，饼图
        const data = []
        for (const [key, value] of Object.entries(response.data.result)) {
          if (key !== 'success' && key !== 'errors') {
            let sum = 0
            value.forEach(function(num) {
              sum += num
            })
            const item = {
              value: sum,
              name: key
            }
            data.push(item)
          }
        }
        if (data.length === 0) {
          const item = {
            value: 0,
            name: '暂无警告'
          }
          data.push(item)
        }
        this.option5.series[0].data = data
        this.isOption3OK = true
      })
    },

    getOption7() {
      this.isOption7OK = false
      analysisApi.getOption7(null, this.selectDate).then((response) => {
        const responseData = response.data.result
        const data = []
        for (let i = 0; i < responseData.length; i++) {
          const item = {
            value: responseData[i].count,
            name: responseData[i].status
          }
          const statusName = responseData[i].status
          const statusCount = responseData[i].count
          if (statusCount !== 0) {
            if (statusName === 0) {
              item.name = '未处理'
            } else if (statusName === 1) {
              item.name = '已处理'
            } else if (statusName === 2) {
              item.name = '已忽略'
            }
            data.push(item)
          }
        }
        if (data.length === 0) {
          const item = {
            value: 0,
            name: '暂无警告'
          }
          data.push(item)
        }
        this.option7.series[0].data = data
        this.isOption7OK = true
      })
    },

    changeDate() {
      this.getOption3()
      this.getOption7()
    },

    fetchData() {
      this.loading = true
      analysisApi.listPage(this.page, this.limit, this.searchObj).then((response) => {
        this.list = response.data.result.list
        this.total = response.data.result.total
      })
      this.loading = false
    },

    fetchList() {
      crawlerApi.getPersonList().then((response) => {
        this.personList = response.data.result
      })
      crawlerApi.getMachineList(this.searchObj.person, this.searchObj.spiderType).then((response) => {
        this.machineList = response.data.result
      })
      crawlerApi.getProjectNameList(this.searchObj.person, this.searchObj.spiderType).then((response) => {
        this.projectNameList = response.data.result
      })
    },

    changePerson() {
      this.fetchList()
      this.fetchData()
    },

    // 联想搜索
    querySearchAsync(queryString, cb) {
      let list = []
      if (!queryString) {
        cb(list)
        return
      } else {
        crawlerApi.querySearchAsync(queryString, this.searchObj.person, this.searchObj.spiderType).then((response) => {
          if (response.code === 200) {
            list = response.data.list
            cb(list)
          }
        })
      }
    },

    // 根据返回的cityId展示不同的cityLabel
    getLabel(cityId) {
      const citylabel = this.cities.find(city => city.value === cityId)
      return citylabel ? citylabel.label : ''
    },

    // 重置搜索表单
    resetData() {
      this.searchObj.codeName = ''
      this.searchObj.projectName = ''
      this.searchObj.machine = ''
      this.searchObj.spiderType = 0
      this.page = 1
      this.limit = 10
      this.$nextTick(() => {
        this.$refs.resetData.$el.blur()
      })
    },

    // 每页展示条数的改变，size：回调函数, 表示当前选中的展示条数
    changePageSize(size) {
      this.limit = size
      this.fetchData()
    },

    // 翻页，page：回调函数, 表示当前选中的页码
    changeCurrentPage(page) {
      this.page = page
      this.fetchData()
    },

    // 表头style
    headStyle() {
      return 'color: black; backgroundColor: ' + variables.globalStyle
    },

    // 列style
    cellStyle({ row, column, rowIndex, columnIndex }) {
      if (row.isTop === 1) {
        return 'backgroundColor: #f2f2f2; height: 50px'
      } else {
        return 'height: 50px'
      }
    }
  }
}
</script>

<style scoped>
  .app-container {
    background-color: rgb(240, 242, 245);
  }
  .cylinder {
    display: flex;
    flex-wrap: nowrap;
  }
  .cylinder-2 {
    margin: 0 10px 20px 10px;
    /*background-color: rgb(202, 212, 226);*/
    background-color: #e2e1e1;
  }
  .cylinder-3 {
    margin: 0 10px 20px 10px;
    background-color: #e2e1e1;
  }
  .selectDateClass {
    flex: 1;
    height: auto;
    margin: 10px 0 0 12px;
  }
  .chart {
    flex: 1;
    height: 400px;
    margin: 0 10px 20px 10px;
    background-color: white;
  }
  .search-button {
    display: flex;
    justify-content: left;
    margin-bottom: 10px;
  }

  .tableClass {
    background-color: white;
    margin: 0 10px 20px 10px;
    padding: 10px;
  }
</style>
<style>

</style>
